package com.ruoyi.hk.websocket;

import com.alibaba.fastjson.JSON;

import com.ruoyi.hk.domain.vo.DocMessageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint("/api/websocket/chat/{userId}")
public class ChatWebSocketServer {
    
    // 用来存放每个客户端对应的ChatWebSocketServer对象
    private static final Map<Long, ChatWebSocketServer> clients = new ConcurrentHashMap<>();
    
    // 与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    
    // 接收userId
    private Long userId;
    
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Long userId) {
        this.session = session;
        this.userId = userId;
        clients.put(userId, this);
        log.info("用户{}连接成功，当前在线人数：{}", userId, clients.size());
    }
    
    @OnClose
    public void onClose() {
        clients.remove(userId);
        log.info("用户{}连接关闭，当前在线人数：{}", userId, clients.size());
    }
    
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到用户{}的消息：{}", userId, message);
        
        try {
            // 解析消息
            DocMessageVo docMessageVo = JSON.parseObject(message, DocMessageVo.class);
            
            // 发送给接收者
            sendMessageToUser(docMessageVo.getReceiverId(), docMessageVo);
            
        } catch (Exception e) {
            log.error("处理消息失败", e);
        }
    }
    
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket发生错误：{}", error.getMessage());
    }
    
    /**
     * 发送消息给指定用户
     */
    public static void sendMessageToUser(Long userId, DocMessageVo message) {
        ChatWebSocketServer client = clients.get(userId);
        if (client != null && client.session.isOpen()) {
            try {
                client.session.getBasicRemote().sendText(JSON.toJSONString(message));
            } catch (IOException e) {
                log.error("发送消息失败", e);
            }
        }
    }
    
    /**
     * 群发消息
     */
    public static void sendMessageToAll(String message) {
        clients.values().forEach(client -> {
            try {
                client.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                log.error("群发消息失败", e);
            }
        });
    }
}